function nper = annuterm(rate,p,pv,fv,due)
%ANNUTERM Number of periods to obtain a future value.
%
%   NPER = annuterm(RATE, P, PV)
%   NPER = annuterm(RATE, P, PV, FV, DUE)
%
%   Optional Inputs: FV, DUE
%
%   Inputs:
%   RATE - Scalar or vector of the periodic interest rate.
%
%      P - Scalar or vector of the periodic payment.
%
%     PV - Scalar or vector of the present value.
%
%   Optional Inputs:
%     FV - Scalar or vector of the future value. Default: FV = 0.
%
%    DUE - Scalar or vector specifying whether the payments are made at the
%          beginning (due = 1) or end (due = 0) of the period. Default: Due = 0.
%
%   Note: To calculate the number of periods needed to pay off a loan, enter
%          the payment or the present value as a negative value.
%
%   Outputs:
%   NPER - Scalar or vector of the number of periods needed to obtain a
%          future value.
%
%   Example:
%      A savings account has a starting balance of $1500. $200 is added at the
%      end of each month and the account pays 9% interest, compounded monthly.
%      How many years will it take to save $5,000?
%
%         nper = annuterm(.09/12, 200, 1500, 5000, 0)
%
%         nper = 15.68 % 15.68 months or 1.31 years
%
%   See also AMORTIZE, ANNURATE, FVFIX, PVFIX.

%   Copyright 1995-2008 The MathWorks, Inc.
%   $Revision: 1.6.2.5 $   $Date: 2008/02/02 13:04:37 $

if nargin < 3
   error('finance:annuterm:tooFewInputs', 'Too few inputs.')
end

if nargin < 5 || isempty(due)
   % Payments made at end of period
   due = zeros(size(p));
end
if nargin < 4 || isempty(fv)
   % Default present initial value is 0.
   fv = zeros(size(p));
end

% Scalar expansion
try
   [rate, p, pv, fv, due] = finargsz('scalar', rate, p, pv, fv, due);

catch E
   error('finance:annuterm:invalidInputDims', E.message);
end

if any(any(due ~= 0 & due ~= 1))
   error('finance:annuterm:invalidDue', 'DUE must be 0 or 1.')
end
if ~all(rate >= 0)
   error('finance:annuterm:invalidRate', 'RATE must be >= 0.')
end

c = 1+rate;
nper = zeros(size(p));
i = find(due == 0);
if ~isempty(i)
   nper(i) = (log((fv(i)-fv(i).*c(i)-p(i))./(pv(i)-pv(i).*...
      c(i)-p(i))))./log(c(i));
end
i = find(due == 1);
if ~isempty(i)
   nper(i) = (log((fv(i)-fv(i).*c(i)-p(i).*c(i))...
      ./(pv(i)-pv(i).*c(i)-p(i).*c(i))))./log(c(i));
end

if (any(~isreal(nper)) || any(nper<0))
   error('finance:annuterm:invalidInputs', ...
      'Input values generated either negative or complex values for NPER.')
end


% [EOF]
